package com.credit.util;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;




/**
 * 订单的util类
 * 
 * @author 
 * 
 */
public class OrderUtil  {
	private static Log log = LogFactory.getLog(OrderUtil.class);
	private static SimpleDateFormat formate = new SimpleDateFormat(
			"yyyyMMddHHmmssSSS");

	// 机器ip 缓存
	private static Map<String, String> mathineCache = new HashMap<String, String>();
	// 国内服务器编号
	// 172.16.108.157 01 计费前端
	// 172.16.108.158 02 计费前端
	// 广东服务器编号
	// 10.8.2.232  03
	// 10.8.2.236  04
	
	// 香港越南服务器编号 50, 51
	// 韩国服务器编码 52,53


	private static String mathineId = "00";

	private static Map<String, Integer> orderDateMap = new HashMap<String, Integer>();

	/**
	 * 短订单号生成 的key
	 */
	public static final String SHORTID_KEY = "Xd56E876";

	/**
	 * 订单类型:1 正常订单
	 */
	public static final int ORDER_TYPE_NOMAL = 1;

	/**
	 * 订单类型:2 补单
	 */
	public static final int ORDER_TYPE_SUPPLEMENT = 2;
	
	public static final int ORDER_TYPE_AVOIDCHEATSUPPLEMENT = 2;
	
	/**
	 * 订单的位数:目前设置8位，其中由时间戳转换来的是7位，加上订单类型位一位组成8位
	 */
	public static final int SHORT_ORDER_ID_PLACES = 7;

	private static final String[] SHORTID_CHARS = { "0", "1", "2", "3", "4",
			"5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h",
			"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
			"v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H",
			"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
			"V", "W", "X", "Y", "Z" };

	private static int ConvertCharToUInt62(char c) {
		switch (c) {
		case '0':
			return 0;
		case '1':
			return 1;
		case '2':
			return 2;
		case '3':
			return 3;
		case '4':
			return 4;
		case '5':
			return 5;
		case '6':
			return 6;
		case '7':
			return 7;
		case '8':
			return 8;
		case '9':
			return 9;
		case 'a':
			return 10;
		case 'b':
			return 11;
		case 'c':
			return 12;
		case 'd':
			return 13;
		case 'e':
			return 14;
		case 'f':
			return 15;
		case 'g':
			return 16;
		case 'h':
			return 17;
		case 'i':
			return 18;
		case 'j':
			return 19;
		case 'k':
			return 20;
		case 'l':
			return 21;
		case 'm':
			return 22;
		case 'n':
			return 23;
		case 'o':
			return 24;
		case 'p':
			return 25;
		case 'q':
			return 26;
		case 'r':
			return 27;
		case 's':
			return 28;
		case 't':
			return 29;
		case 'u':
			return 30;
		case 'v':
			return 31;
		case 'w':
			return 32;
		case 'x':
			return 33;
		case 'y':
			return 34;
		case 'z':
			return 35;
		case 'A':
			return 36;
		case 'B':
			return 37;
		case 'C':
			return 38;
		case 'D':
			return 39;
		case 'E':
			return 40;
		case 'F':
			return 41;
		case 'G':
			return 42;
		case 'H':
			return 43;
		case 'I':
			return 44;
		case 'J':
			return 45;
		case 'K':
			return 46;
		case 'L':
			return 47;
		case 'M':
			return 48;
		case 'N':
			return 49;
		case 'O':
			return 50;
		case 'P':
			return 51;
		case 'Q':
			return 52;
		case 'R':
			return 53;
		case 'S':
			return 54;
		case 'T':
			return 55;
		case 'U':
			return 56;
		case 'V':
			return 57;
		case 'W':
			return 58;
		case 'X':
			return 59;
		case 'Y':
			return 60;
		case 'Z':
			return 61;
		}
		return 0;
	}

	public static final String[] ORDERSTATUS = new String[] { "发货失败","通知失败","支付失败","下单成功", "支付成功",
			"通知成功", "发货成功"};

	// 支付通道协议
	public final static String SMS_CHANNEL_TYPE = "11";
	public final static String HTTP_CHANNEL_TYPE = "12";
	public final static String APP_CHANNEL_TYPE = "13";
	public final static String SDK_CHANNEL_TYPE = "14";
	public final static String CALL_CHANNEL_TYPE = "15";
	// 支付通道协议 end

	// 产品类型
	public final static String NETGAME_PRODUCT_TYPE = "01";
	public final static String SINGLEGAME_PRODUCT_TYPE = "02";
	public final static String MUSIC_PRODUCT_TYPE = "03";
	public final static String BOOK_PRODUCT_TYPE = "04";
	public final static String PICTURE_PRODUCT_TYPE = "05";
	public final static String APP_PRODUCT_TYPE = "06";
	public final static String WAP_PRODUCT_TYPE = "07";
	public final static String VEDIO_PRODUCT_TYPE = "08";
	public final static String IVR_PRODUCT_TYPE = "09";
	public final static String SMS_PRODUCT_TYPE = "10";
	public final static String WEB_PRODUCT_TYPE = "11";
	public final static String M_SMS_VEDIO_PRODUCT_TYPE = "12";
	// 产品类型 end
	
	//网源类型
	public final static String CLIENT_NETSOURCE = "1";
	public final static String WEB_NETSOURCE = "2";
	public final static String WECHAT_NETSOURCE = "3";
	public final static String WAP_NETSOURCE = "4";
	public final static String FORUM_NETSOURCE = "5";
	public final static String GSSC_NETSOURCE = "6";
	public final static String OTHER_NETSOURCE = "9";
	//网源类型 end

	public final static String RMB_CURRENCY = "1";

	/**
	 * 获取订单号
	 * 
	 * @return
	 */
	public static synchronized String getOrderId() {

		return getOrderId(ORDER_TYPE_NOMAL);

	}

	/**
	 * 获取订单号
	 * 
	 * @param orderType
	 *            :订单类型:0为正常，1为补单
	 * @return
	 */
	public static synchronized String getOrderId(int orderType) {

		String orderId = "";

		String orderDateStr = formate.format(new Date());
		String key = "111" + orderDateStr;

		Integer count = orderDateMap.get(key);

		if (count == null) {
			clear();
			count = 0;
			orderDateMap.put(key, count);
			log.info("毫秒为：[" + key + "]中没有订单生成，计数器的size为：["
					+ orderDateMap.size() + "]");
		} else {
			count++;
			orderDateMap.put(key, count);

			log.info("毫秒为：[" + orderDateStr + "]中有[" + count
					+ "] 个订单生成，计数器的size为：[" + orderDateMap.size() + "]");
		}
		log.info("当前的订单号中计数器为：[" + count + "]");
		orderId = key + (count < 10 ? "0" + count : count);

		return orderId;
	}

	/**
	 * 清空缓存
	 */
	private static void clear() {
		orderDateMap.clear();

	}

	/**
	 * 转换订单号
	 * 
	 * @param shortOrderId
	 * @return
	 */
	private static String getUid(String shortOrderId) {
		char[] c = shortOrderId.toCharArray();
		long cheng = ConvertCharToUInt62(c[0]);
		for (int i = 1; i < c.length; i++)
			cheng = cheng * 62 + ConvertCharToUInt62(c[i]);
		return String.valueOf(cheng);
	}

	private static String addZerospite(String addstring) {

		int addstrleng = addstring.length();
		int i = 8 - addstrleng;
		switch (i) {
		case 1:
			addstring = "0" + addstring;
			break;
		case 2:
			addstring = "00" + addstring;
			break;
		case 3:
			addstring = "000" + addstring;
			break;
		case 4:
			addstring = "0000" + addstring;
			break;
		case 5:
			addstring = "00000" + addstring;
			break;
		case 6:
			addstring = "000000" + addstring;
			break;
		}
		return addstring;
	}

	// TentoN(这里是你想转换的数 ,这里是你想转换为多少进制 2-62之间）
	private static String tentoN(long value, int number) {
		if (number <= 1 || number > SHORTID_CHARS.length) {
			throw new RuntimeException("Faild");
		}
		// 负数处理
		if (value < 0) {
			return "-" + tentoN(0 - value, number);
		}
		if (value < number) {
			return SHORTID_CHARS[(int) value];
		} else {
			long n = value % (long) number;
			String st = (tentoN(value / number, number) + SHORTID_CHARS[(int) n]);
			return st;
		}
	}

	/**
	 * 将传入的短订单号转换成长订单号 将16位订单号转换成23位订单号 注意:只支持23位的奇数位订单号
	 * 
	 * @param shortOrderId
	 * @return
	 */
	public static String translateOrderId2Long(String shortOrderId) {
		int length = shortOrderId.length();
		int seperatorNum = length / 2;

		String prefix = getUid(shortOrderId.substring(0, seperatorNum));
		String suffix = getUid(shortOrderId.substring(seperatorNum, length));
		
		while(prefix.length() < 11){
			prefix = "0" + prefix;
			
		}
		
		while(suffix.length() < 11){
			suffix = "0" + suffix;
			
		}
		
		
		return prefix + suffix;
		
		// 这块特殊处理下吧，在压缩订单的时候00002014042510154600900
		// 处理的2014042510154600900部分，如果按照前9后10压缩，会变成201404251 和
		// 0154600900所以导致解压出错
		// 这里跟长度判断下，为后面补充0. 只有奇数订单位可使用此算法还原，否则还原会出错
//		String orderId = prefix
//				+ (suffix.length() == prefix.length() ? "0" + suffix : suffix);
//
//		StringBuilder zeroStr = new StringBuilder();
//		if (orderId.length() < 23) {
//			int len = 22 - orderId.length();
//			for (int i = 0; i < len; i++)
//				zeroStr.append("0");
//		}

//		return zeroStr.toString() + orderId;
	}

	/**
	 * 将传入的长订单号转换成短订单号 将23位订单号转换成16位订单号
	 * 
	 * @param longOrderId
	 * @return
	 */
	public static String translateOrderId2Short(String longOrderId) {

//		BigDecimal orderLongId = new BigDecimal(longOrderId);
//		String strOrderId = orderLongId.toString();
		int length = longOrderId.length();

		int seperatorNum = length / 2;

		String prefix = StringUtils.EMPTY;

		prefix = longOrderId.substring(0, seperatorNum);

		String suffix = longOrderId.substring(seperatorNum);

		return addZerospite(tentoN(Long.valueOf(prefix), 62))
				+ addZerospite(tentoN(Long.valueOf(suffix), 62));
	}

/*	*//**
	 * 默认生成8位的短订单号
	 * 
	 * @param id
	 * @return
	 *//*
	public static String getShortOrderId(String id) {
		String shortOrderId = HexadecimalAndDecimalismUtil._10_to_62(System.currentTimeMillis(), SHORT_ORDER_ID_PLACES);
		shortOrderId = id.substring(2, 3) + shortOrderId;
		//添加到Rsdis
//		ShortOrderIdCacheMgr.addShortOrderId(shortOrderId, id);
		return shortOrderId;
//		return getShortOrderId(id, 8);
	}*/
	
	/**
	 * 根据长id生成短id号
	 * 
	 * @param id
	 *            ,长id号
	 * @param length
	 *            ,返回的长度
	 * @return
	 */
	public static String getShortOrderId(String id, int length) {

		if (length <= 0) {
			return null;
		}

		// 对传入id进行 MD5 加密
		String hex = DigestUtils.md5Hex(SHORTID_KEY + id);

		// 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
		String sTempSubString = hex.substring(0, 8);

		// 使用 Long 型来转换
		long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
		String outChars = "";
		for (int j = 0; j < length; j++) {
			// 把得到的值与 0x0000003D 进行位与运算，取得字符数组 chars 索引
			long index = 0x0000003D & lHexLong;
			// 把取得的字符相加
			outChars += SHORTID_CHARS[(int) index];
			// 每次循环按位右移 5 位
			lHexLong = lHexLong >> 5;
		}

		return new String(outChars);
	}
	
	/**
	 * 获取补单单号
	 * @param orderId 原始订单号
	 * @return
	 */
	public static String getSupplementOrderId(String orderId) {
		return ORDER_TYPE_SUPPLEMENT + orderId.substring(1);
	}
	
	/**
	 * 补单号，反作弊补单以2开头
	 * @param orderId
	 * @return
	 */
	public static String getAvoidCheatSupplementOrderId(String orderId) {
		return ORDER_TYPE_AVOIDCHEATSUPPLEMENT + orderId.substring(1);
	}

/*	@Override
	public void afterPropertiesSet() throws Exception {
		String machineIp = InetAddress.getLocalHost().getHostAddress();
		mathineId = StringUtils.isEmpty(mathineCache.get(machineIp)) ? "01"
				: mathineCache.get(machineIp);
	}*/

	
	
	
	
	/**
	 * 将订单号按照3-4-4-4-4-3进行分割
	 * 0022014090111170470300 分割为 002 2014 0901 1117 0470 300
	 * @param orderid
	 * @return
	 */
	public static String splitOrderId(String orderid){
		String sbString = " ";
		for(int i=3;i<orderid.length();i=i+4){
			if(orderid.length()-i<4){
				sbString+=orderid.substring(i);
			}else{
				sbString += orderid.substring(i, i+4)+" ";
			}
		}
		orderid = orderid.substring(0,3)+sbString;
		return orderid;
	}

	
	public static String getNo(){
		Random rnd = new Random();
		int num = 100 + rnd.nextInt(900);
		
		String orderDateStr = formate.format(new Date())+num;
		
		return orderDateStr;
	}
	
//	public static void main(String[] args) throws Exception {
//		 int iCount = 10000;
//		 int iDup = 0;
//		 Map map = new HashMap<String, String>();
//		 String orderId = "";
//		 String shortOrderId = "";
//		 for (int i = 0; i < iCount; i++) {
//		 orderId = OrderUtil.getOrderId();
//		 shortOrderId = OrderUtil.getShortOrderId(orderId);
//		 if (map.containsKey(shortOrderId)) {
//			 iDup++;
//			 System.out.println("[shortOrderId:" + shortOrderId + "][orderId:"
//			 + orderId + "][OldorderId:"
//			 + map.get(shortOrderId) + "][i:" + i
//			 + "][iDup:" + iDup);
//			
//			 }
//			 //
//			 System.out.println("orderId:"+orderId+"][shortOrderId:"+shortOrderId+"][i:"+i);
//			
//			 map.put(shortOrderId, orderId);
//			
//			 }
//		//
//		// System.out.println("end orderId:" + orderId + "][shortOrderId:"
//		// + shortOrderId + "]");
//		//
//		 orderId = "0002014070214522106275";
//		 shortOrderId = OrderUtil.getShortOrderId(orderId);
//		
//		 System.out.println("end orderId:" + orderId + "][shortOrderId:"
//		 + shortOrderId + "]");
//		
//		 orderId = "00020140702145220687134";
//		 shortOrderId = OrderUtil.getShortOrderId(orderId);
//		 System.out.println("end orderId:" + orderId + "][shortOrderId:"
//		 + shortOrderId + "]");
//
//		// System.out.println(ssid);
//		// System.out.println(translateOrderId2Long(ssid));
//		
//		"0992014070717431590900".substring(3, 9);
//		"0992014070717431590900".substring(3, 11);
//	}
	
/*	public static  EfdPayOrder createOrder(EfdUser user,String payType,String payChannleId) {
		EfdPayOrder order = new EfdPayOrder();
		order.setOrderid(OrderUtil.getOrderId());
		order.setAmount(new BigDecimal(10));
		order.setCreatetime(new Date());
		order.setOpenid(user.getHeId());
		order.setPaychannelid(payChannleId);
		order.setProdid(payType);
		order.setStatus("0");
		order.setCreatetime(new Date());
		order.setUpdatetime(new Date());
		order.setUserid(user.getId());
		EfdPayOrderService efdPayOrderService = (EfdPayOrderService) ApplicationContextUtils.getBean("efdPayOrderService");
		efdPayOrderService.insertOrder(order);
		
		return order;
	}*/
}
